#-*- codeing = utf-8 -*-
#@Time : 2020/9/25 21:15
#@Author : 阳某
#@File : 马赛克图.py
#@Software : PyCharm
import cv2
import glob
import argparse
import numpy as np
from tqdm import tqdm       #   进度条
from itertools import product       #   迭代器
# from 包或者库 import 函数或者库

# 图片文件
def parseArgs():
    parser = argparse.ArgumentParser('拼接马赛克图片')
    parser.add_argument('--targetpath',type=str,default='muban/1.jpg',help='目标图像路径')
    parser.add_argument('--outputpath',type=str,default='output.jpg',help='输出图像路径')
    parser.add_argument('--sourcepath',type=str,default='sourceimages',help='用于拼接图像所有的原图像文件夹路径')
    parser.add_argument('--blocksize',type=int,default=15,help='马赛克块的大小')
    args = parser.parse_args()
    return args
# 输入
# 计算处理
# 输出
# 展示

# 读取所有源图片并计算对应的颜色平均值
def readSourceImages(sourcepath,blocksize):
    print('开始读取图片')
    sourceimages = []   #取到合法的图片放入列表
    avgcolors = []                    #平均颜色列表
    # for path in tqdm(range(100)):
    #     # print(path)
    for path in tqdm(glob.glob('{}/*jpg'.format(sourcepath))):
        image = cv2.imread(path,cv2.IMREAD_CPLOR)
        # print(image.shape)      #(255,255,255,87)   RGB,,RGBA
        if image.shape[-1] !=3:
            continue
        image = cv2.resize(image,(blocksize,blocksize))
        # 计算当前图像颜色平均值,元组
        avgcolor = np.sum(np.sum(image,axis=0),axis=0) / (blocksize*blocksize)
        sourceimages.append(image)
        avgcolors.append(avgcolor)
    print('结束读取')
    # array[1 2 3] 数组
    return sourceimages,np.array(avgcolors)
def main(args):
    targetimage = cv2.imread(args.targetpath)
    outputimage = np.zeros(targetimage.shape,np.uint8)
    sourceimages,avgcolors = readSourceImages(args.sourcepath,args.blocksize)
    print('开始制作')
    # 生成迭代器，遍历坐标
    '''
    这个速度慢，for嵌套其实很慢
    for x in range(10):
        for y in range(10):
            print(x,y)
    '''
    # 列表推导式很快
    for i, j in tqdm(product(range(int(targetimage.shape[1]/args.blocksize)),range(int(targetimage.shape[0]/args.blocksize)))):
        # 线性代数和求范式
        block = targetimage[j * args.blocksize:(j+1)*args.blocksize,i*args.blocksize:(i+1) * args.blocksize, :]
        avgcolor = np.sum(np.sum(block,axis=0),axis=0) / (args.blocksize*args.blocksize)
        distances = np.linalg.norm(avgcolor-avgcolors,axis=1)
        idx = np.argmin(distances)
        outputimage[j * args.blocksize:(j + 1) * args.blocksize,i *args.blocksize:(i + 1)*args.blocksize, :]=sourceimages[idx]
    cv2.imwrite(args.outputpath,outputimage)
    cv2.imread('result',outputimage)
    print('制作完成')
if __name__ == '__main__':
    # main(parseArgs())
    args = parseArgs()
    main(args)